#ifndef QCDICTITEMMODEL_H
#define QCDICTITEMMODEL_H

#include <QAbstractItemModel>
#include <any>

class QcDictItemModel : public QAbstractItemModel
{
    Q_OBJECT

public:
    explicit QcDictItemModel(QObject *parent = nullptr);
    ~QcDictItemModel();

    // 共5列数据，第1列：英文；第2列：音标；第3列：词性；第4列：中文释义；第5列：示例
    enum KeColumnTyle
    {
        K_WORD,
        K_PRON,
        K_POS,
        K_CHINESE,
        K_EXAMPLE,
        K_COLUMN_COUNT
    };

    // Header:
    QVariant headerData(int section,
                        Qt::Orientation orientation,
                        int role = Qt::DisplayRole) const override;

    // Basic functionality:
    QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override;
    QModelIndex parent(const QModelIndex &index) const override;

    int rowCount(const QModelIndex &parent = QModelIndex()) const override;
    int columnCount(const QModelIndex &parent = QModelIndex()) const override;

    // Fetch data dynamically:
    bool hasChildren(const QModelIndex &parent = QModelIndex()) const override;

    bool canFetchMore(const QModelIndex &parent) const override;
    void fetchMore(const QModelIndex &parent) override;

    QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;

    // Editable:
    bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override;

    Qt::ItemFlags flags(const QModelIndex &index) const override;

    bool insertRows(int row, int count, const QModelIndex &parent = QModelIndex()) override;
    bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex()) override;

    QString dictRootPath() const;

    // 从路径到index
    QModelIndex indexFromPath(const QString& path) const;

    QModelIndex indexFromName(const QString& name, const QModelIndex& parent) const;

private:

    // 保存字典数据的路径
    QString modelDir_() const;

    // 字典文件名
    QString dictFileName_() const;

    struct KpDictItem
    {
        KpDictItem* parent{ nullptr };
        QString name;
        bool isWord{ false }; // 是否叶子节点，若true则代表当前item为英文单词，否则为层级目录
        bool fetched{ false };
        std::vector<std::any> children;

        // 强制输入父节点，不然容易出错
        KpDictItem(KpDictItem* p) : parent(p) {}
    };

    KpDictItem* item_(const QModelIndex &index) const;

    QString fullPath_(KpDictItem* parent) const;

    QString dictPath_(KpDictItem* parent) const;

    // 从内部词典文件加载词条到parent.children
    void loadWords_(KpDictItem* parent);

    // 存储parent.children到内部词典文件（替换原文件）
    bool saveWords_(KpDictItem* parent);

    QString formatWordLine_(KpDictItem* item);

    void deleteItem_(KpDictItem* p);

    KpDictItem* root_;
};

#endif // QCDICTITEMMODEL_H
